iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0

說明

useRef Hook 保存的值,不會因為每次元件 Render 而重新被創造。在初始化後,使用 useRef 回傳出來的物件,會始終指向同一個 Reference。

語法

// 宣告
const refObject = useRef('initialValue');
// 取得 => 使用 .current 屬性取得值
console.log(refObject.current) // 'initialValue'
// 變更不會觸發 render
refObject.current = 'newValue'

useState 與 useRef 比較

useState - 更新 State 都會重新 Render

執行結果:https://codepen.io/lala-lee-jobs/pen/abGZNNO?editors=0011

useRef - 更新 Ref 不會重新 Render

執行結果:https://codepen.io/lala-lee-jobs/pen/YzLpZPJ?editors=0011

應用

因為 useRef 不會因為更新元件而被改變 Reference 的特性,讓它常常被應用在以下的情境

指定為某個DOM元素的參考,因此可在程式中直接操作DOM

有一個輸入框,按下按鈕後,Focus 到該輸入框。

function App() {
  // 宣告
  const inputRef = useRef(null);
  // 在程式中操作 input DOM 的 Ref
  const focusInput = () => {
    inputRef.current.focus();
  };

  return (
    <>
      <!-- 指定 inputRef 為 此 input DOM 的參考 -->
      <input type="text" ref={inputRef} />
      <button onClick={focusInput}>Focus Input</button>
    </>
  );
}

執行結果:https://codepen.io/lala-lee-jobs/pen/ZEoBeXJ?editors=0011

跨生命週期保存某個值,像是 setTimeout/setInterval 的 Timer Id

function App() {
  const timer = useRef(null);
  const [count, setCount] = useState(0);

  useEffect(() => {
    timer.current = setInterval(() => {
      setCount(count => count + 1);
    }, 1000);
    return () => clearInterval(timer.current);
  },[]);

  return (
    <>
      <span>開始計時</span>
      <span>{count}</span>
    </>
  );
}

執行結果:https://codepen.io/lala-lee-jobs/pen/KKRNmRB?editors=0011

在每次 Render 保存前次 State 的值

function App() {
  const [inputValue, setInputValue] = React.useState('');
  const previousInputValue = React.useRef('');

  React.useEffect(() => {
    previousInputValue.current = inputValue;
  }, [inputValue]);

  return (
    <>
      <input
        type="text"
        value={inputValue}
        onChange={(e) => setInputValue(e.target.value)}
      />
      <h2>Current Value: {inputValue}</h2>
      <h2>Previous Value: {previousInputValue.current}</h2>
    </>
  );
}

執行結果:https://codepen.io/lala-lee-jobs/pen/zYjowLV?editors=0011

Next

通常會在原生 HTML DOM 元素上使用 useRef,用以取得該 DOM 節點的參考。但是自製的元件就無法對其使用 useRef,要如何取得自製元件的參考,就是接下來要介紹的 forwardRef 的功能。

Reference

https://www.w3schools.com/react/react_useref.asp

https://juejin.cn/post/6854573209639976974

https://github.com/puxiao/react-hook-tutorial/blob/master/12%20useRef%E5%9F%BA%E7%A1%80%E7%94%A8%E6%B3%95.md

https://github.com/puxiao/react-hook-tutorial/blob/master/13%20useImperativeHandle%E5%9F%BA%E7%A1%80%E7%94%A8%E6%B3%95.md


上一篇
Day 11 建立可重複在專案使用的客製化 React Hook
下一篇
Day 13 React.forwardRef (HOC)、useImperativeHandle
系列文
開始搞懂React生態系30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言